package com.econ.powercloud.ems.service.biz;

import com.econ.powercloud.common.base.facade.enums.StatusType;
import com.econ.powercloud.common.base.facade.exception.CommonRuntimeException;
import com.econ.powercloud.common.base.facade.pojo.MsgResult;
import com.econ.powercloud.common.base.facade.pojo.PageResult;
import com.econ.powercloud.common.base.facade.util.JacksonUtil;
import com.econ.powercloud.console.facade.domain.*;
import com.econ.powercloud.console.facade.enums.EdgeCloudSwitchStatusEnum;
import com.econ.powercloud.console.facade.enums.EdgeServiceType;
import com.econ.powercloud.console.facade.enums.EdgeStrategyTypeEnum;
import com.econ.powercloud.ems.common.enums.DeviceOperationMsgType;
import com.econ.powercloud.ems.dal.entity.EmsDevice;
import com.econ.powercloud.ems.dal.entity.EmsEnergyEquipment;
import com.econ.powercloud.ems.pojo.DeviceOperationDetailsVO;
import com.econ.powercloud.ems.pojo.DeviceOperationRecordVO;
import com.econ.powercloud.ems.pojo.SvcPushParams;
import com.econ.powercloud.ems.pojo.SvcPushPayload;
import com.econ.powercloud.ems.pojo.requestVO.DeviceOperationSearchRequestVO;
import com.econ.powercloud.ems.rpc.IFeignPowerNodeConsoleClient;
import com.econ.powercloud.ems.service.dao.EmsDeviceDAO;
import com.econ.powercloud.ems.service.dao.EmsEnergyEquipmentDAO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author jwc
 * @date 2022/07/21
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class DeviceSyncMsgService {

    private final IFeignPowerNodeConsoleClient iFeignPowerNodeConsoleClient;
    private final EmsEnergyEquipmentDAO emsEnergyEquipmentDAO;
    private final EmsDeviceDAO emsDeviceDAO;

    /**
     * 获取操作记录下的客户端ip有哪些
     * @return
     */
    public List<String> getClientIpList(){
        MsgResult<List<String>> msgResult = iFeignPowerNodeConsoleClient.searchClientIp();
        if(StatusType.OK.getCode() != msgResult.getStatus()){
            throw new CommonRuntimeException(StatusType.FEIGN_ERROR, StatusType.FEIGN_ERROR.getStatusText());
        }
        return msgResult.getData();
    }

    public PageResult<List<DeviceOperationRecordVO>> search(DeviceOperationSearchRequestVO requestVO, Integer pageNo, Integer pageSize) {
        EdgePlatformSyncMsgSearchRequestVO feignRequestVO = JacksonUtil.convertToObj(requestVO, EdgePlatformSyncMsgSearchRequestVO.class);
        feignRequestVO.setPageNo(pageNo);
        feignRequestVO.setPageSize(pageSize);
        List<EmsDevice> emsDeviceList;
        if (StringUtils.isEmpty(requestVO.getDeviceCode()) && StringUtils.isEmpty(requestVO.getEnergyEquipmentId())) {
            emsDeviceList = Collections.EMPTY_LIST;
        } else {
            emsDeviceList = emsDeviceDAO.selectByDeviceCodeAndEquipmentId(requestVO.getDeviceCode(), requestVO.getEnergyEquipmentId());
            //没有找到设备，不需要调feign查询了，直接返回
            if (CollectionUtils.isEmpty(emsDeviceList)) {
                return PageResult.<List<DeviceOperationRecordVO>>builder().pageNo(pageNo).totalCount(0).data(Collections.EMPTY_LIST).build();
            }
        }
        final List<String> initDeviceCodeList = emsDeviceList.stream().map(EmsDevice::getInitDeviceCode).collect(Collectors.toList());
        feignRequestVO.setDeviceCodeList(initDeviceCodeList);
        //封装操作类型的查询参数
        if (null != requestVO.getOperationType()) {
            feignRequestVO.setServiceId(DeviceOperationMsgType.fromCode(requestVO.getOperationType()).getServiceId());
            feignRequestVO.setServiceCode(DeviceOperationMsgType.fromCode(requestVO.getOperationType()).getServiceCode());
        }
        MsgResult<PageResult<List<EdgePlatformSyncMsgVO>>> msgResult = iFeignPowerNodeConsoleClient.searchDeviceOperationRecord(feignRequestVO);
        if(StatusType.OK.getCode() != msgResult.getStatus()){
            throw new CommonRuntimeException(StatusType.FEIGN_ERROR, StatusType.FEIGN_ERROR.getStatusText());
        }
        PageResult<List<EdgePlatformSyncMsgVO>> pageResult = msgResult.getData();
        List<DeviceOperationRecordVO> recordVOList = JacksonUtil.convertToList(pageResult.getData(), DeviceOperationRecordVO.class);
        fillOtherInfo(recordVOList);
        PageResult<List<DeviceOperationRecordVO>> newPageResult = PageResult.<List<DeviceOperationRecordVO>>builder().pageNo(pageResult.getPageNo()).totalCount(pageResult.getTotalCount()).data(recordVOList).build();
        return newPageResult;
    }

    /**
     * 补充DeviceOperationRecordVO一些字段的值
     * @param recordVOList
     */
    public void fillOtherInfo(List<DeviceOperationRecordVO> recordVOList) {
        if(CollectionUtils.isEmpty(recordVOList)){
            return;
        }
        final Map<String, EmsDevice> stringEmsDeviceMap = emsDeviceDAO.selectByModuleCode().stream().collect(Collectors.toMap(EmsDevice::getInitDeviceCode, Function.identity()));
        final Map<String, EmsEnergyEquipment> stringEmsEnergyEquipmentMap = emsEnergyEquipmentDAO.list().stream().collect(Collectors.toMap(EmsEnergyEquipment::getEnergyEquipmentId, Function.identity()));
        for (DeviceOperationRecordVO obj : recordVOList) {
            String deviceName = stringEmsDeviceMap.get(obj.getDeviceCode())==null ? "" : stringEmsDeviceMap.get(obj.getDeviceCode()).getDeviceName();
            String equipmentName = "";
            String equipmentId = "";
            EmsDevice emsDevice = stringEmsDeviceMap.get(obj.getDeviceCode());
            if (null != emsDevice) {
                EmsEnergyEquipment emsEnergyEquipment = stringEmsEnergyEquipmentMap.get(emsDevice.getEnergyEquipmentId());
                if (emsEnergyEquipment != null) {
                    equipmentName = emsEnergyEquipment.getEnergyEquipmentName();
                    equipmentId = emsEnergyEquipment.getEnergyEquipmentId();
                }
            }
            obj.setDeviceName(deviceName);
            obj.setEnergyEquipmentId(equipmentId);
            obj.setEnergyEquipmentName(equipmentName);
            if (obj.getServiceId().equals(DeviceOperationMsgType.CLOUDSWITCH.getServiceId())) {
                obj.setOperationTypeName(EdgeCloudSwitchStatusEnum.fromCode(Integer.valueOf(obj.getServiceCode())).getDesc());
            } else {
                obj.setOperationTypeName(DeviceOperationMsgType.from(obj.getServiceId(), obj.getServiceCode()).getDesc());
            }
            //只有遥控、遥调，需要显示点号的数据，其余类型不需要，所以置空
            if (!StringUtils.equals(obj.getServiceId(), EdgeServiceType.YK.getServiceId())
                    && !StringUtils.equals(obj.getServiceId(), EdgeServiceType.YT.getServiceId())) {
                obj.setServiceName(StringUtils.EMPTY);
            }
        }
    }

    /**
     * 获取设备操作记录的详情
     * @param msgPid
     * @return
     */
    public DeviceOperationDetailsVO listDetails(Integer msgPid){
        DeviceOperationDetailsVO detailsVO = new DeviceOperationDetailsVO();
        MsgResult<EdgePlatformSyncMsgDetailVO> msgResult = iFeignPowerNodeConsoleClient.msgDetails(msgPid);
        if(StatusType.OK.getCode() != msgResult.getStatus()){
            throw new CommonRuntimeException(StatusType.FEIGN_ERROR, StatusType.FEIGN_ERROR.getStatusText());
        }
        EdgePlatformSyncMsgDetailVO vo = msgResult.getData();
        if (vo == null) {
            return null;
        }
        detailsVO.setPayload(vo.getPayload());
        SvcPushPayload svcPushPayload = JacksonUtil.parseObject(vo.getPayload(), SvcPushPayload.class);
        SvcPushParams svcPushParams = svcPushPayload.getParams();
        if (StringUtils.equals(svcPushParams.getServiceId(), EdgeServiceType.STRATEGY.getServiceId())) { //strategy
            EdgeStrategyRequestVO strategyRequestVO = JacksonUtil.convertToObj(svcPushParams.getValue(), EdgeStrategyRequestVO.class);
            if (strategyRequestVO.getType().equals(EdgeStrategyTypeEnum.PEAK_VALLEY_BALANCE.getCode())) { //移峰填谷才需要图的数据
                List<EdgeStrategyPeakValleyBalance> list = JacksonUtil.convertToList((List) strategyRequestVO.getData(), EdgeStrategyPeakValleyBalance.class);
                detailsVO.setChartData(list);
            }
        }

        return detailsVO;
    }
}
